package june.asynchronoustest;

import java.io.BufferedInputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class AsynchronousTestActivity extends Activity {
    /** Called when the activity is first created. */
	
	String serchString = "";
	a_Adapter aA;
	Handler h = new Handler();
	NaverParser np;
	ArrayList<NpSerchItem> arryNp;
	LinearLayout vl;
	Button close;
	ImageView v;
	
	EditText et;
	Button bt;
	ListView lv;
	
	Thread t;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        vl = (LinearLayout)findViewById(R.id.vl);
        close = (Button)findViewById(R.id.button2);
        close.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				vl.setVisibility(View.INVISIBLE);
			}
		});
        v = (ImageView)findViewById(R.id.imageView1);
        
        lv = (ListView)findViewById(R.id.listView1);   
        lv.setOnItemClickListener(OICL);
//        list_setting(serchString);
        
        et = (EditText)findViewById(R.id.editText1);
        bt = (Button)findViewById(R.id.button1);
        bt.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				serchString = et.getText().toString();
				list_setting(serchString);
			}
		});
    }
    
    
    OnItemClickListener OICL = new OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			Log.i("june", "아이템 클릭 : " + arryNp.get(arg2).w + ", " + arryNp.get(arg2).h);
			
			
			float fw = Float.parseFloat(arryNp.get(arg2).w);
			float fh = Float.parseFloat(arryNp.get(arg2).h);
			float s = 0;
			float reh = 0;
			float rew = 0;
			
			if(fw > 300){
				s = (fw-dipToPx(300))/fw;
				reh = fh - (fh * s);
			}
			
			if(fh > dipToPx(400) || reh > dipToPx(400)){
				s = (fh-dipToPx(400))/fh;
				rew = fw - (fw * s);
			} else {
				rew = 300;
			}
				
			Log.i("june", "s : " + s + ", reh : " + reh + "rew : " + rew);
			
			Bitmap a = GetImageFromURL(arryNp.get(arg2).link, rew, reh);
			
			vl.setVisibility(View.VISIBLE);
			v.setImageBitmap(a);
		}
	};
    
    
    /**
     * 검색어를 가지고 파서를 동작시킨다. 자료는 바로 셋팅.
     * @param serchString
     */
    public void list_setting(String serchString){
    	np = new NaverParser(AsynchronousTestActivity.this, serchString, h2);
    	np.execute();
    }
    
    /**
     * 리스트 갱신 핸들러.
     */
    Handler h2 = new Handler(){
    	@Override
    	public void handleMessage(Message msg) {
    		// TODO Auto-generated method stub
    		if(msg.arg1 == 100){
    			Log.i("june", "핸들러 호출");
    			arryNp = np.getter();
    			aA = new a_Adapter(AsynchronousTestActivity.this, arryNp);
    	        lv.setAdapter(aA);
    		}
    		super.handleMessage(msg);
    	}
    };
    
    
    /**
     * 커스텀어답터.
     * @author HackJuneLee
     *
     */
    class a_Adapter extends BaseAdapter {
    	
    	ArrayList<NpSerchItem> item;
    	Context c;
    	Bitmap bm = null;
    	
    	public a_Adapter(Context c, ArrayList<NpSerchItem> arryNp){
    		this.c = c;
    		item = arryNp;
    	}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return item.size();
		}

		@Override
		public Object getItem(int arg0) {
			// TODO Auto-generated method stub
			return item.get(arg0);
		}

		@Override
		public long getItemId(int arg0) {
			// TODO Auto-generated method stub
			return arg0;
		}

		@Override
		public View getView(final int arg0, View arg1, ViewGroup arg2) {
			
			//리스트의 한 행을 이루는 row를 코드상으로 불러온다.
			LayoutInflater inflater = ((Activity)c).getLayoutInflater();
			View row = inflater.inflate(R.layout.row, null);
			
			//row에 존재하는 텍스트뷰이기 때문에 row.find를 해야합니다.
			TextView tv = (TextView)row.findViewById(R.id.textView1);
			Log.i("june", "a : " + item.get(arg0).title);
			tv.setText(item.get(arg0).title);
			
			final ImageView iv = (ImageView)row.findViewById(R.id.imageView1);
			iv.setImageResource(R.drawable.icon);
			
			if(item.get(arg0).bm == null){
				newThread(iv, arg0);
			} 
			
			//보관되어있는 비트맵을 꺼내서 바로셋팅.
			else {
				iv.setImageBitmap(item.get(arg0).bm);
			}	
			
			
			return row;
		}
    	
		/**
		 * 파이널 선언이 키 포인트!
		 * 새로은 스레드를 만들때 아예 겟뷰에서 간섭하지 못하게
		 * 파이널로 분류하고 메소드에 고정하여 넘긴다.
		 * 넘어갈때의 값들은 모두 고유함으로 값 변경에 대한 문제를 차단한다.
		 * @param iv row에서 가져온 이미지뷰. 
		 * @param index 겟뷰에서 각 row에 해당하는 인덱스값.
		 */
		public void newThread(final ImageView iv , final int index){
	
			//이미지 변환과정이 오래걸림으로 스레드를 이용한 비동기 처리를 시작합니다.
			//리스트 하나의 행당 스레드가 하나씩 돌고있다고 생각해야합니다.
			new Thread(new Runnable() {
				
				//전역 대신 새로운 비트맵을 생성.
				Bitmap btm = null;
				@Override
				public void run() {
					
					btm = GetImageFromURL(item.get(index).thumbURL);
					
					//비트맵을 만들었지만 새로운 스레드가 메인 ui에 간섭하기시작하면(쉽게말해 set메소드를 실행하면.)
					//바로 에러가뜹니다. 이에 대해서는 수많은 이슈와 개발자의 눈물이 검색포탈에 포함되어있죠.
					//그 이슈를 해결하는 방법이 바로 포스트!.
					h.post(new Runnable() {
						
						@Override
						public void run() {
							// TODO Auto-generated method stub
							iv.setImageBitmap(btm);
							//한번만들어진놈은 또 비트맵변환을 할필요없겠죠.
							//그러니까 따로 보존합니다.	
							item.get(index).bm = btm;
						}
					});
				}
			}).start();
				
			
	    }
    }
    
    
    
    
    /**
     * uri주소를 가지고 비트맵으로 변환하는 메소드. 시간이 오래걸림으로 비동기작업을 추천합니다.
     * @param strImageURL 비트맵으로 변환할 uri주소.
     * @return
     */
    private Bitmap GetImageFromURL(String strImageURL) 
    {
        Bitmap imgBitmap = null;
        try
        {
        	URL url = new URL(strImageURL);
        	URLConnection conn = url.openConnection();
        	conn.connect();
        	
        	int nSize = conn.getContentLength();
        	BufferedInputStream bis = new BufferedInputStream(conn.getInputStream(), nSize);
        	imgBitmap = BitmapFactory.decodeStream(bis);
        	
        	bis.close();
        }
        catch (Exception e)
        {
        	e.printStackTrace();
        }
        
        return imgBitmap;
    }
    
    private Bitmap GetImageFromURL(String strImageURL, float w, float h) 
    {
        Bitmap imgBitmap = null;
        Bitmap reimgBitmap = null;
        try
        {
        	URL url = new URL(strImageURL);
        	URLConnection conn = url.openConnection();
        	conn.connect();
        	
        	int nSize = conn.getContentLength();
        	BufferedInputStream bis = new BufferedInputStream(conn.getInputStream(), nSize);
        	imgBitmap = BitmapFactory.decodeStream(bis);
        	
        	reimgBitmap = Bitmap.createScaledBitmap(imgBitmap, (int)w, (int)h, false);
        	
        	bis.close();
        }
        catch (Exception e)
        {
        	e.printStackTrace();
        }
        
        return imgBitmap;
    }
    
    private int dipToPx(float number) {

        int num = (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP, number, 
                    getResources().getDisplayMetrics());

        return num;
    }
     
    private int pxToDip(float number) {
    	
    	float scale = getResources().getDisplayMetrics().density;
    	int num = (int)( number / scale );
    	
    	return num;
    }
}